#include "sc.h"

extern int SC_INPUT_BUFSIZE, SC_OUTPUT_BUFSIZE;

NeighbourhoodToPixelOp()
interpolate(in stream unsigned char i[-1..0][-1..0],
            out stream unsigned char *o)
{
  *o = i[-1][0]*0.24 + i[-1][-1]*0.24 + i[0][-1]*0.24 + i[0][0]*0.24;
}

NeighbourhoodToPixelOp()
sobelx(in stream unsigned char i[-1..1][-1..1],
       out stream int *o)
{
  int x, y, temp;
  
  temp = 0;
  for (y=-1; y < 2; y++)
    for (x=-1; x < 2; x=x+2)
      temp = temp + x*i[y][x];
      
  *o = temp;
}

NeighbourhoodToPixelOp()
sobely(in stream unsigned char i[-1..1][-1..1],
       out stream int *o)
{
  int x, y, temp;
  
  temp = 0;
  for (x=-1; x < 2; x++)
    for (y=-1; y < 2; y=y+2)
      temp = temp + y*i[y][x];
      
  *o = temp;
}

PixelToPixelOp()
magnitude(in stream int *i1,
  	  in stream int *i2,
	  out stream int *o)
{
  int temp;

  if (*i1 < 0) temp = -*i1;
  else         temp = *i1;
  if (*i2 < 0) temp = temp + -*i2;
  else         temp = temp + *i2;

  *o = temp;
}

PixelToPixelOp()
binarize(in stream unsigned char *i,
  	 out stream unsigned char *o,
	 in int *threshold = scint(128))
{
  *o = *i > *threshold;
}

ReductionOp()
imgMax(in stream unsigned char *i, in int* prevmax, out int* outmax)
{
  if (*i > *prevmax)
    *outmax = *i;
}

PixelToPixelOp()
mul(in stream unsigned char *i,
    out stream unsigned char *o,
    in double *factor)
{
  *o = *i * *factor;
}

GlobalOp()
delay(in stream unsigned char *i, 
      out stream unsigned char *o)
{
  int y, x;

  for (y=0; y < _lines; y++)
    for (x=0; x < _stride; x++)
      o[y][x] = i[y][x];
}

int main(int argc, char **argv)
{
  int i=0, j, k, maxval, maxc, dummy;
  STREAM a, b, c, d, e, f, g;

  scInit(argc, argv);

  SC_INPUT_BUFSIZE = SC_OUTPUT_BUFSIZE = 1024*1024*3;

  for (i=0; i < 10; i++)
  {
    capture(&a);
    interpolate(&a, &a);

    imgMax(&a, scint(0), &j);
    _block(&j);
    
    while (j  > 128)
    {
      mul(&a, &a, scdbl(0.9));
      imgMax(&a, scint(0), &j);
      _block(&j);
    }
    
    sobelx(&a, &b);
    sobely(&a, &c);
    magnitude(&b, &c, &a);
    _finalize(&b);
    _finalize(&c);

    if (i % 2)
      display(&a);

    _block(&a);
  }

  return scExit();
}
